/*******************************************************************************
 * Copyright (c) 2010, 2011 SYSTEMA GmbH.
 * All rights reserved.
 *
 * Contributors:
 *     SYSTEMA GmbH - initial API and implementation
 *******************************************************************************/

package de.sr.gwtdemo.shared.util;

import java.util.HashMap;
import java.util.List;

/**
 * A utility class for strings.
 * 
 * @author Jens Hildebrand
 * @since 17.03.2011
 */
public class StringUtil {

	public static final String EMPTY_STRING = "";

	public static final String[] EMPTY_STRING_ARRAY = new String[0];

	public static final String NULL_STRING = "null";

	public static final String UNKNOWN_VALUE = "?";

	public static final String LINE_SEPARATOR = "\n"; // FIXME check if correct

	public static final String NL = LINE_SEPARATOR;

	public static final String ARRAY_START = "[";

	public static final String ARRAY_SEPARATOR = ",";

	public static final String ARRAY_END = "]";

	public static final String LIST_START = "(";

	public static final String LIST_SEPARATOR = ",";

	public static final String LIST_END = ")";

	public static final String SPLIT_SEPARATOR_DEFAULT = ",";

	public static boolean contains(List<String> list, String value) {
		return contains(list, value, false);
	}

	public static boolean contains(List<String> list, String value, boolean ignoreCase) {
		if (list != null && value != null) {
			for (String otherValue : list) {
				if (equals(value, otherValue, ignoreCase))
					return true;
			}
		}
		return false;
	}

	public static boolean contains(String[] array, String value, boolean ignoreCase) {
		if (array != null && value != null) {
			for (String otherValue : array) {
				if (equals(value, otherValue, ignoreCase))
					return true;
			}
		}
		return false;
	}

	public static boolean equals(String s1, String s2) {
		return equals(s1, s2, false);
	}

	public static boolean equals(String s1, String s2, boolean ignoreCase) {
		if (s1 != null && s2 != null) {
			if (ignoreCase) {
				if (s1.equalsIgnoreCase(s2))
					return true;
			} else {
				if (s1.equals(s2))
					return true;
			}
		}

		if (s1 == null && s2 == null)
			return true;

		return false;
	}

	public static boolean isNullOrEmpty(String value) {
		return value == null || value.length() == 0;
	}
	
	public static boolean isNullOrEmptyOrNullString(String value) {
		return value == null || value.length() == 0 || value.equals(NULL_STRING); 
	}

	/**
	 * Makes a not-null string from a given string list by used default values
	 * for start (]), separator (,)and end (]).
	 */
	public static String mkString(List<String> list) {
		String[] array = list != null ? list.toArray(EMPTY_STRING_ARRAY) : EMPTY_STRING_ARRAY;
		return mkString(array, LIST_START, LIST_SEPARATOR, LIST_END);
	}

	/**
	 * Makes a not-null string from a given string list by used default values
	 * for start, separator and end.
	 */
	public static String mkString(List<String> list, String start, String separator, String end) {
		String[] array = list != null ? list.toArray(EMPTY_STRING_ARRAY) : EMPTY_STRING_ARRAY;
		return mkString(array, start, separator, end);
	}

	/**
	 * Makes a not-null string from a given string array by used default values
	 * for start (]), separator (,)and end (]).
	 */
	public static String mkString(String[] array) {
		return mkString(array, ARRAY_START, ARRAY_SEPARATOR, ARRAY_END);
	}

	/**
	 * Makes a not-null string from a given string array.
	 */
	public static String mkString(String[] array, String start, String separator, String end) {
		StringBuffer result = new StringBuffer();
		if (start == null)
			start = EMPTY_STRING;
		if (separator == null)
			separator = EMPTY_STRING;
		if (end == null)
			end = EMPTY_STRING;

		result.append(start);
		if (array != null) {
			for (int i = 0; i < array.length; i++) {
				if (i > 0)
					result.append(separator);
				String value = array[i];
				result.append(value);
			}
		}
		result.append(end);

		return result.toString();
	}

	public static String notNull(String value) {
		return value != null ? value : EMPTY_STRING;
	}

	public static String notNullWithNullStringCheck(String value) {
		return value != null && !NULL_STRING.equals(value) ? value : EMPTY_STRING;
	}

	/**
	 * Quotates a not-null string from a given string. A null-string will be
	 * replaced by
	 * <code>null<code>, other strings are surrounded with quotation marks.
	 */
	public static String quotString(String string) {
		if (string == null)
			return NULL_STRING;

		return "\"" + string + "\"";
	}

	/**
	 * Splits the given <em>string</em> to an array using the
	 * {@link #SPLIT_SEPARATOR_DEFAULT}.
	 * 
	 * @see #split(String, String)
	 */
	public static String[] split(String string) {
		return split(string, SPLIT_SEPARATOR_DEFAULT);
	}

	/**
	 * Splits the given <em>string</em> to an array using the <em>separator</em>
	 * . Note that {@link String#split} is used inside, which requires a RegEx.
	 * This means that splitting by "." has to be specified with "\\.".
	 */
	public static String[] split(String string, String separator) {
		if (string == null || string.length() == 0)
			return EMPTY_STRING_ARRAY;

		if (separator == null || separator.length() == 0)
			return new String[] { string };

		return string.split(separator);
	}

	/**
	 * Splits the given <em>string</em> to a map using the <em>equalsSign</em>
	 * and <em>separator</em>. This method uses {@link #split(String, String)}.
	 * 
	 * @see #split(String, String)
	 */
	public static HashMap<String, String> splitToMap(String string, String equalsSign, String separator) {
		HashMap<String, String> result = new HashMap<String, String>();

		String[] items = split(string, separator);
		for (String item : items) {
			String[] split = split(item, equalsSign);
			String key = split[0];
			String value = split.length > 1 ? split[1] : EMPTY_STRING;
			result.put(key, value);
		}
		return result;
	}

	public static String[] toArray(List<String> list) {
		if (list == null)
			return EMPTY_STRING_ARRAY;
		return list.toArray(EMPTY_STRING_ARRAY);
	}

	public static String trim(String value) {
		return value != null ? value.trim() : EMPTY_STRING;
	}
}
